<template>
  <view class="container">
	  <!-- 开始扫码按钮 
	  <view class="controls">
	    <button @click="startScan">开始扫码</button>
	    <button @click="stopScan" v-if="isScanning">停止扫码</button>
	  </view> -->
    <!-- 状态指示器 -->
    <view class="status-indicator">
      <view :class="['status-dot', scannerStatus]"></view>
      <text class="status-text">扫描状态: {{ statusMessage }}</text>
     <!-- <text class="scan-count">扫描计数: {{ scanCount }}</text>-->
    </view>

    <!-- 扫码历史 -->
    <view class="history">
      <text>扫码历史（共{{ group_id - 1 }}组）：</text>
      <scroll-view scroll-y="true" class="history-scroll">
        <view v-for="(item, index) in scanHistory" :key="index" class="history-item">
          <text>{{ item }}</text>
        </view>
      </scroll-view>
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { onShow,onNavigationBarButtonTap  } from '@dcloudio/uni-app'

// ========== 状态 ==========
const comparisonResult = ref("")
const scanHistory = ref<string[]>([])
const isScanning = ref(false)
const scannerStatus = ref("ready") // ready, scanning, error
const statusMessage = ref("正在初始化扫描功能...")
const scanCount = ref(0)

let serverIP = ref("")       // 服务器 IP
let writeToDB = ref(false)    // 是否写入数据库

let group_id = 1
let packageCode: string | null = null
let supplierCode: string | null = null

onNavigationBarButtonTap((e) => {
  console.log("导航栏按钮点击:", e)
  if (e.index === 0) {
	  // 第0个按钮（settings.png）
	  goToSettings()
  } else if (e.index === 1) {
    // 第1个按钮（clear.png）
    clearHistory()
  }
})

// ========== 设置加载 ==========
function loadSettings() {
  serverIP.value = uni.getStorageSync("server_ip") || ""
  writeToDB.value = uni.getStorageSync("write_to_db") ?? false
}

// ========== iData 扫描插件 ==========
let barcodeModel: any = null
let globalEvent: any = null

let lastScanTime = 0
const SCAN_DEBOUNCE_INTERVAL = 300
let lastScanBarcode = ""

// 初始化扫描
const initScanner = () => {
  // #ifdef APP-PLUS
  try {
    barcodeModel = uni.requireNativePlugin("iData-BarcodePlugin-BarcodeModule")
    globalEvent = uni.requireNativePlugin('globalEvent')

    barcodeModel.initScan((ret: any) => {
      if (ret && ret.code === 'success') {
        scannerStatus.value = "ready"
        statusMessage.value = "就绪，可使用物理按键扫描"

        barcodeModel.setScanKeyEnable(true, (enableRet: any) => {
          if (enableRet && enableRet.code === 'success') {
            scannerStatus.value = "ready"
            statusMessage.value = "物理按键已启用，可开始扫描"

            barcodeModel.continueScan(false, () => {})
          }
        })
      } else {
        scannerStatus.value = "error"
        statusMessage.value = `扫描初始化失败: ${JSON.stringify(ret)}`
      }
    })

    globalEvent.addEventListener('iDataBarcodeEvent', (e: any) => {
      const currentTime = Date.now()
      const currentBarcode = e?.barcode || ""

      if (currentTime - lastScanTime < SCAN_DEBOUNCE_INTERVAL && currentBarcode === lastScanBarcode) {
        return
      }

      lastScanTime = currentTime
      lastScanBarcode = currentBarcode
      scanCount.value++

      if (e && e.barcode) {
        handleScanResult(e.barcode)
      }
    })
  } catch (error) {
    scannerStatus.value = "error"
    statusMessage.value = "扫描插件初始化异常"
  }
  // #endif
}

// ========== 工具函数 ==========
function asStr(v: any): string {
  return String(v ?? "")
}

function isPackageCode(code: any): boolean {
  return asStr(code) !== "" && code.indexOf("&") === -1
}

function isSupplierCode(code: any): boolean {
  return asStr(code) !== "" && code.indexOf("&") !== -1
}

function extractPackageCodeFromSupplierCode(supplierCode: string): string | null {
  const parts = supplierCode.split("&")
  return parts.length >= 3 ? parts[2] : null
}

function resetCodes() {
  packageCode = null
  supplierCode = null
  scanHistory.value.unshift(`第${group_id}组：${comparisonResult.value}`)
  group_id++
}

// ========== 音频 ==========
const successAudio = uni.createInnerAudioContext()
successAudio.src = '/static/audio/success.mp3'

const failAudio = uni.createInnerAudioContext()
failAudio.src = '/static/audio/fail.mp3'

function playSuccessSound() {
  successAudio.stop()
  successAudio.play()
}

function playFailSound() {
  failAudio.stop()
  failAudio.play()
}

// ========== 核心逻辑 ==========
function saveScanResultToServer(code: string, result: string) {
    if (!writeToDB.value) {
      console.log("⚠️ 当前设置为不写入数据库，跳过保存")
      return
    }
  
    if (!serverIP.value) {
      uni.showToast({ title: "请先配置服务器IP", icon: "none" })
      return
    }

  const url = `http://${serverIP.value}/api/scan`
  const timestamp = formatDateTime()

  uni.request({
    url,
    method: "POST",
    data: {
      group_id,
      package_code: packageCode,
      supplier_code: supplierCode,
      result,
      timestamp
    },
    timeout: 1000, // 5秒超时
    success: (res) => {
      console.log("✅ 上传成功:", res.data)
    },
    fail: (err) => {
      console.error("❌ 上传失败:", err)
      // 检查是否为网络错误或服务器不可达
      let errorMsg = "数据上传失败"
      if (err.errMsg && err.errMsg.includes("fail")) {
        errorMsg = "服务器连接失败，请检查网络或服务器是否开启"
      }
      uni.showModal({
        title: "提示",
        content: errorMsg,
        showCancel: false,
        confirmText: "确定"
      })
    }
  })
}

function processScannedCode(raw: string) {
  const code = asStr(raw)
  if (!code) return

  let codeType = ""
  if (isPackageCode(code)) {
    packageCode = code
    codeType = "翻包二维码"
  } else if (isSupplierCode(code)) {
    supplierCode = code
    codeType = "供应商标签二维码"
  } else {
    codeType = "未知二维码"
  }

  scanHistory.value.unshift(`${codeType}: ${code}`)

  if (packageCode != null && supplierCode != null) {
    let extracted = extractPackageCodeFromSupplierCode(supplierCode as string)
    if (extracted == null) {
      comparisonResult.value = "供应商二维码格式错误"
      playFailSound()
      saveScanResultToServer(code, "格式错误")
      resetCodes()
      return
    }
	
	// 如果 翻包二维码 没有后缀，则提取 供应商标签二维码 前面同样的字符进行对比
	// if (packageCode.indexOf("-") === -1) {
	// 	extracted=extracted.slice(0,packageCode.length)
	// }

    if (extracted === packageCode) {
      comparisonResult.value = "比对结果: 一致 ✅"
      playSuccessSound()
      saveScanResultToServer(code, "一致")
    } else {
      comparisonResult.value = "比对结果: 不一致 ❌"
      playFailSound()
      uni.showModal({
        title: "提示",
        content: `比对结果不一致，请检查二维码！
翻包二维码: ${packageCode}
供应商二维码: ${supplierCode}`,
        showCancel: false
      })
      saveScanResultToServer(code, "不一致")
    }
    resetCodes()
  }
}

function handleScanResult(code: string) {
  processScannedCode(code)
}

// ================= 手机扫码入口 =================
function startScan_SJ() {
  // 开始新的比对 → 清空历史
  scanHistory.value = []
  comparisonResult.value = ""

  uni.scanCode({
    onlyFromCamera: true,
    success: (res) => {
      const scannedCode = (res["result"] as string) ?? (res["code"] as string) ?? ""
      handleScanResult(scannedCode)   // ✅ 统一入口
    },
    fail: () => {
      uni.showToast({ title: "扫码失败", icon: "none" })
    }
  })
}

// ========== PDA 扫描控制 ==========
function startScan() {
  scanHistory.value = []
  comparisonResult.value = ""
  isScanning.value = true
  scannerStatus.value = "scanning"
  statusMessage.value = "正在扫描中..."
  scanCount.value = 0

  // #ifdef APP-PLUS
  if (barcodeModel) {
    barcodeModel.scanStart(() => {})
  }
  // #endif
}

function stopScan() {
  isScanning.value = false
  scannerStatus.value = "ready"
  statusMessage.value = "已停止扫描"

  // #ifdef APP-PLUS
  if (barcodeModel) {
    barcodeModel.scanStop(() => {})
  }
  // #endif
}

function formatDateTime(date: Date = new Date()): string {
  const y = date.getFullYear()
  const m = String(date.getMonth() + 1).padStart(2, '0')
  const d = String(date.getDate()).padStart(2, '0')
  const hh = String(date.getHours()).padStart(2, '0')
  const mm = String(date.getMinutes()).padStart(2, '0')
  const ss = String(date.getSeconds()).padStart(2, '0')
  return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}

// ========== 跳转设置 ==========
function goToSettings() {
  uni.navigateTo({
    url: '/pages/settings/settings'
  })
}

function clearHistory() {
  scanHistory.value = []
  scanCount.value = 0
  group_id = 1
  uni.showToast({ title: "历史已清空", icon: "success" })
}


// ========== 生命周期 ==========
onMounted(() => {
  loadSettings()
  initScanner()
})

onShow(() => {
  loadSettings()
})


onUnmounted(() => {
  // #ifdef APP-PLUS
  if (barcodeModel) {
    barcodeModel.closeScan(() => {})
  }
  if (globalEvent) {
    globalEvent.removeEventListener('iDataBarcodeEvent')
  }
  // #endif
})
</script>


<style>
.container {
  flex: 1;
  flex-direction: column;
  padding: 20rpx;
  height: 100vh;
  box-sizing: border-box;
}

.status-indicator {
  display: flex;
  flex-direction: column;
  margin-bottom: 20rpx;
  padding: 15rpx;
  border-radius: 10rpx;
  background-color: #f9f9f9;
}

.status-line {
  display: flex;
  align-items: center;
  margin-bottom: 5rpx;
}

.status-dot {
  width: 20rpx;
  height: 20rpx;
  border-radius: 50%;
  margin-right: 15rpx;
}

.status-dot.ready {
  background-color: #4cd964;
}

.status-dot.scanning {
  background-color: #007aff;
}

.status-dot.error {
  background-color: #dd524d;
}

.status-text, .scan-count {
  font-size: 28rpx;
  color: #555;
  margin-right: 20rpx;
}

.controls {
  margin-bottom: 20rpx;
  display: flex;
  flex-direction: row;
  justify-content: space-around;
  flex-wrap: wrap;
}

.controls button {
  margin: 5rpx;
  min-width: 200rpx;
}

.result {
  margin-bottom: 20rpx;
  padding: 20rpx;
  background-color: #f9f9f9;
  border-radius: 10rpx;
}

.result-text {
  font-size: 32rpx;
  font-weight: bold;
  color: #333;
}

.history {
  flex: 1;
}

.history-scroll {
  max-height: 800rpx;
  border: 1rpx solid #eee;
  border-radius: 5rpx;
  padding: 10rpx;
}

.history-item {
  padding: 8rpx;
  border-bottom: 1rpx solid #f0f0f0;
  font-size: 24rpx;
  color: #666;
}

.top-bar {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  padding: 15rpx 20rpx;
  background-color: #f0f0f0;
  border-bottom: 1rpx solid #ddd;
}

.title {
  font-size: 32rpx;
  font-weight: bold;
  color: #333;
}

.top-bar button {
  font-size: 26rpx;
  padding: 10rpx 20rpx;
  border-radius: 8rpx;
  border: none;
  color: white;
  background-color: #007aff;
  cursor: pointer;
}

.top-bar button:active {
  background-color: #0056cc;
}

.settings-btn {
  background-color: #34c759;
}

.settings-btn:active {
  background-color: #2a9d4a;
}
</style>
